package myJs.user.workflowMission

import myJs.Implicits._
import myJs.Utils._
import scala.scalajs.js.Dynamic.{global => g}
import myJs.myPkg.bootstrap.Bootstrap.default._
import myJs.myPkg.jquery._
import myJs.myPkg.{ColumnOptions, ExportOptions, LayerOptions, Swal, SwalOptions, TableOptions}
import myJs.tool.Tool
import myJs.tool.Tool._
import myJs.user.workflow.WorkflowTool
import org.scalajs.dom.ext.Ajax
import org.scalajs.dom.{Element, document, window}
import scalatags.Text.all._
import shared.Pojo.GroupDataKind

import scala.collection.immutable.SeqMap
import org.scalajs.macrotaskexecutor.MacrotaskExecutor.Implicits._
import scala.scalajs.js
import scala.scalajs.js.JSConverters._
import scala.scalajs.js.JSON

/**
 * Created by yz on 14/8/2020
 */
trait MissionResult extends WorkflowTool {

  val tableId = "table"
  val modalId = "viewModal"
  val reRunModalId = "reRunModal"

  def getMissionId: String

  override def registerEvent = {
    println("==")
    super.registerEvent
    $(document.body).on("click", ".myViewFile", "", (y: Element) => {
      val fileName = $(y).dataValue
      viewFile(fileName)
    })
    $(s"#${modalId}").on("shown.bs.modal", () => {
      val fileName = getFileName
      refreshData(fileName)
    })

  }

  def getFileName = {
    $(s"#${modalId} #fileName").text().trim
  }

  def viewFile(fileName: String) = {
    $(s"#${modalId} #fileName").text(fileName)
    $(s"#${modalId}").modal("show")
  }

  def getFilesExistInfo(fileNames: js.Array[String]) = {
    val fileExistInfoUrl = g.jsRoutes.controllers.MissionController.getFileNamesExistInfo().url.toString
    val dict = js.Dictionary("fileNames" -> fileNames)
    val data = JSON.stringify(dict)
    Ajax.post(url = s"${fileExistInfoUrl}", data = data, headers = Map("Content-Type" -> "application/json")).map { xhr =>
      xhr.responseText.toJDB
    }
  }

  def refreshMissionInfo(missionId: String) = {
    val url = g.jsRoutes.controllers.WorkflowController.getMissionById().url.toString
    Ajax.get(url = s"${url.noCache}&missionId=${missionId}").map { xhr =>
      val dict = JSON.parse(xhr.responseText).toJDJAn
      val fileNames = dict("input").toJArS
      getFilesExistInfo(fileNames).map { infoDict =>
        dict.foreach { case (k, v) =>
          val trueV = k match {
            case "kind" => Tool.getWFKindA(v.toString).render
            case "state" => Tool.successA.render
            case "input" =>
              val vs = v.toJArS
              Tool.getInputByName("file").`val`(vs.head)
              if (vs.size > 1) {
                Tool.getInputByName("groupFile").`val`(vs(1))
              }
              vs.map { v =>
                if (infoDict(v)) {
                  val names = v.split("/")
                  val url = Tool.getDetailUrl(names(0))
                  a(href := s"${url}?fileName=${v}", target := "_blank", s"${v}")
                } else {
                  span(v)
                }
              }.mkString("&nbsp;&nbsp;")
            case x if x != "arg" => span(v.toString).render
          }
          $(s"#mission #${k}").html(trueV)
        }
      }
    }
  }

  lazy val operateColumn = js.Array(
    ColumnOptions.field("operate").title(messages("operations")).formatter(operateFmt).filterControl("clear")
  )

  def operateFmt: js.Function = {
    (v: js.Any, row: js.Dictionary[js.Any]) =>
      val fileName = row("fileName").toString
      val step = fileName.split("\\.").head
      val downloadUrl = g.jsRoutes.controllers.WorkflowController.downloadResultFile().url.toString
      val downloadStr = a(title := messages("download"),
        href := s"${downloadUrl}?missionId=${getMissionId}&fileName=${fileName}", cursor.pointer,
        span(em(cls := "fa fa-download"))
      )

      val detailViewStr = a(title := messages("viewDetails"), `class` := "myViewFile", dataValue := s"${row("fileName")}",
        span(em(cls := "fa fa-eye"))
      )

      val reRunStr = a(title := messages("rerunWithModificantion"), `class` := "myReRunShow", dataValue := s"${step}",
        span(em(cls := "fa fa-refresh"))
      )

      val rs = if (List(".pdf", ".zip", ".svg", ".json").exists(x => row("fileName").toString.endsWith(x))) {
        List(downloadStr)
      } else List(detailViewStr, downloadStr, reRunStr)
      rs.mkString("&nbsp;")
  }

  def tbFmt(columnName: String): js.Function = (v: js.Any, row: js.Dictionary[js.Any]) => columnName match {
    case "step" => val fileName = row("fileName").toString
      fileName.split("\\.").head
    case _ => v
  }

  def refreshFileInfo(missionId: String) = {
    val url = g.jsRoutes.controllers.WorkflowController.getResultFileInfo().url.toString
    Ajax.get(url = s"${url.noCache}&missionId=${missionId}", headers = Map("Content-Type" -> "application/json")).map { xhr =>
      val rs = xhr.responseText.toJDJAn
      val headerMap = SeqMap("step" -> s"${messages("step")}", "fileName" -> messages("file"), "soft" -> messages("modules"), "rowNum" -> messages("rowsInDataFile"),
        "intro" -> messages("note"))
      val columnNames = headerMap.keyList
      val columns = columnNames.map { columnName =>
        val fmt = tbFmt(columnName)
        val title = headerMap.getOrElse(columnName, columnName)
        ColumnOptions.field(columnName).title(title).sortable(true).formatter(fmt)
      }.toJSArray.concat(operateColumn)
      val options = TableOptions.data(rs).columns(columns).pagination(false)
      $(s"#${tableId}").bootstrapTable("destroy").bootstrapTable(options)
    }
  }

  def expStyle(columnName: String, firstName: String): js.Function = (v: js.Any, row: js.Dictionary[Any]) => columnName match {
    case x if x == firstName =>
      js.Dictionary()
    case _ => js.Dictionary("css" -> js.Dictionary(
      "padding" -> 0
    ))
  }

  def expFmt(columnName: String, firstName: String): js.Function = (v: js.Any, row: js.Dictionary[js.Any]) => columnName match {
    case x if x == firstName =>
      val json = v.asInstanceOf[js.Dictionary[js.Any]]
      val str = json.myGet("value")
      span(
        str
      )
    case otherName =>
      val json = v.asInstanceOf[js.Dictionary[js.Any]]
      val html = cellView(json, row)
      html
  }

  def cellView(json: js.Dictionary[js.Any], row: js.Dictionary[js.Any]) = {
    val color = json.myGet("color")
    val v = json.myGet("value")
    val bgColor = if (color.nonBlank) {
      s"#${color.drop(2)}"
    } else {
      "white"
    }
    div(width := "100%",
      height := 40,
      backgroundColor := bgColor,
      div(
        paddingLeft := 8,
        paddingRight := 8,
        paddingTop := 10,
        paddingBottom := 10,
        v
      )
    )
  }

  def refreshData(fileName: String) = {
    val index = layer.load(1, Tool.layerOptions.shade(js.Array("0.1", "#fff")))
    val url = g.jsRoutes.controllers.WorkflowController.getFileData().url.toString
    Ajax.get(url = s"${url.noCache}&missionId=${getMissionId}&fileName=${fileName}", headers = Map("Content-Type" -> "application/json")).map { xhr =>
      val rs = xhr.responseText.toJDJAn
      val columnNames = rs("columnNames").asInstanceOf[js.Array[String]]
      val columns = columnNames.zipWithIndex.map { case (columnName, index) =>
        fileName.fileNameSuffix match {
          case "xlsx" =>
            val fmt = expFmt(columnName, columnNames.head)
            val style = expStyle(columnName, columnNames.head)
            ColumnOptions.field(index.toString).title(columnName).sortable(true).cellStyle(style).formatter(fmt)
          case _ =>
            val fmt = columnName
            ColumnOptions.field(index.toString).title(columnName).sortable(true)
        }
      }
      val options = TableOptions.data(rs("array")).columns(columns).pagination(true).
        pageList(js.Array("10", "25", "50", "100", "all")).fixedColumns(true).fixedNumber(1)
      $(s"#${modalId} #${tableId}").bootstrapTable("destroy").bootstrapTable(options)
      layer.close(index)
    }
  }

}
